package http

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"sync"
	"time"

	"internal-net-bridge-server/internal/common"

	"github.com/gin-gonic/gin"
)

// ============================================================================
// HTTP/2响应处理器 - 混合模式服务端
// ============================================================================
//
// 功能：
// 1. 接收客户端通过HTTP/2发送的响应数据
// 2. 将响应数据转发给等待的浏览器请求
// 3. 管理等待响应的请求队列
//
// 混合模式工作流程：
// 1. 浏览器 → HTTP → 服务端（普通HTTP请求）
// 2. 服务端 → QUIC → 客户端（推送请求）
// 3. 客户端 → HTTP/2 → 服务端（发送响应）← 本文件处理
// 4. 服务端 → HTTP → 浏览器（转发响应）
//
// ============================================================================

// PendingResponse 等待响应的请求
type PendingResponse struct {
	RequestID    string
	BrowserConn  io.Writer   // 🔥 浏览器连接(net.Conn)，用于直接写入响应
	ResponseChan chan []byte // 🔥 用于小文件的完整响应
	ErrorChan    chan error
	StartTime    time.Time
	Timeout      time.Duration
	Ctx          *gin.Context // Gin上下文（可选）
}

// HTTP2ResponseHandler HTTP/2响应处理器
type HTTP2ResponseHandler struct {
	pendingResponses sync.Map // requestID -> *PendingResponse
	statusManager    *common.RequestStatusManager
}

// NewHTTP2ResponseHandler 创建HTTP/2响应处理器
func NewHTTP2ResponseHandler() *HTTP2ResponseHandler {
	return &HTTP2ResponseHandler{
		statusManager: common.NewRequestStatusManager(),
	}
}

// RegisterPendingResponse 注册一个等待响应的请求
func (h *HTTP2ResponseHandler) RegisterPendingResponse(requestID string, browserConn io.Writer, timeout time.Duration) *PendingResponse {
	pr := &PendingResponse{
		RequestID:    requestID,
		BrowserConn:  browserConn,
		ResponseChan: make(chan []byte, 1),
		ErrorChan:    make(chan error, 1),
		StartTime:    time.Now(),
		Timeout:      timeout,
	}

	h.pendingResponses.Store(requestID, pr)
	// 🔥 设置初始状态为等待响应
	h.statusManager.SetStatus(requestID, common.RequestStatusPending)

	log.Printf("📝 [HTTP/2响应] 注册等待响应: RequestID=%s, 超时=%v", requestID[:8]+"...", timeout)

	return pr
}

// RegisterPendingResponseWithContext 注册一个等待响应的请求（带Gin上下文）
func (h *HTTP2ResponseHandler) RegisterPendingResponseWithContext(requestID string, c *gin.Context, timeout time.Duration) *PendingResponse {
	pr := &PendingResponse{
		RequestID:    requestID,
		BrowserConn:  c.Writer,
		ResponseChan: make(chan []byte, 1),
		ErrorChan:    make(chan error, 1),
		StartTime:    time.Now(),
		Timeout:      timeout,
		Ctx:          c,
	}

	h.pendingResponses.Store(requestID, pr)
	// 🔥 设置初始状态为等待响应
	h.statusManager.SetStatus(requestID, common.RequestStatusPending)

	log.Printf("📝 [HTTP/2响应] 注册等待响应: RequestID=%s, 超时=%v", requestID[:8]+"...", timeout)

	return pr
}

// UnregisterPendingResponse 注销等待响应的请求
func (h *HTTP2ResponseHandler) UnregisterPendingResponse(requestID string) {
	h.pendingResponses.Delete(requestID)
	// 🔥 清理状态
	h.statusManager.DeleteStatus(requestID)
	log.Printf("🗑️  [HTTP/2响应] 注销等待响应: RequestID=%s", requestID[:8]+"...")
}

// HandleHTTP2Response 处理客户端通过HTTP/2发送的响应
// 路由：POST /tunnel/response/:requestID
// 🔥🔥🔥 关键优化：流式转发,边读边写,避免大文件OOM
func (h *HTTP2ResponseHandler) HandleHTTP2Response(c *gin.Context) {
	requestID := c.Param("requestID")

	// 验证隧道ID（可选，从Header获取）
	tunnelID := c.GetHeader("X-Tunnel-ID")
	if tunnelID == "" {
		log.Printf("⚠️  [HTTP/2响应] 缺少X-Tunnel-ID: RequestID=%s", requestID[:8]+"...")
	}

	log.Printf("📥 [HTTP/2响应] 收到流式响应: RequestID=%s, TunnelID=%s", requestID[:8]+"...", tunnelID[:8]+"...")

	// 查找等待响应的请求
	value, ok := h.pendingResponses.Load(requestID)
	if !ok {
		log.Printf("⚠️  [HTTP/2响应] 请求不存在或已超时: RequestID=%s", requestID[:8]+"...")
		// 🔥 返回特殊状态头，告诉客户端停止发送
		c.Header("X-Request-Status", "NOT_FOUND")
		c.JSON(http.StatusNotFound, gin.H{"error": "请求不存在或已超时", "should_stop": true})
		return
	}

	pr := value.(*PendingResponse)

	// 🔥 设置状态为正在接收
	h.statusManager.SetStatus(requestID, common.RequestStatusReceiving)

	// 🔥🔥🔥 流式转发优化：带缓冲的流式传输,支持更好的流控
	// 🚀 使用64KB缓冲区(平衡内存和性能)
	startTime := time.Now()
	buffer := make([]byte, 64*1024) // 64KB缓冲区
	written := int64(0)

	// 🔥 检查浏览器连接是否支持CloseNotify
	closeNotify := c.Writer.CloseNotify()

	// 🔥🔥🔥 关键优化：使用带缓冲的Channel避免阻塞
	errChan := make(chan error, 1)

	// 🚀 启动读取goroutine，避免阻塞select
	go func() {
		for {
			n, readErr := c.Request.Body.Read(buffer)
			if n > 0 {
				// 写入浏览器连接
				nw, writeErr := pr.BrowserConn.Write(buffer[:n])
				if nw > 0 {
					written += int64(nw)
				}
				if writeErr != nil {
					log.Printf("❌ [HTTP/2响应] 写入浏览器失败: %v, RequestID=%s", writeErr, requestID[:8]+"...")
					errChan <- writeErr
					return
				}
				if n != nw {
					err := fmt.Errorf("写入不完整: 读取%d, 写入%d", n, nw)
					log.Printf("❌ [HTTP/2响应] %v, RequestID=%s", err, requestID[:8]+"...")
					errChan <- err
					return
				}
			}
			if readErr != nil {
				if readErr == io.EOF {
					// 正常结束
					errChan <- nil
					return
				}
				log.Printf("❌ [HTTP/2响应] 读取失败: %v, RequestID=%s", readErr, requestID[:8]+"...")
				errChan <- readErr
				return
			}
		}
	}()

	// 🔥🔥🔥 监控浏览器断开和传输完成
	select {
	case <-closeNotify:
		log.Printf("🚫 [HTTP/2响应] 浏览器已断开连接,停止传输: RequestID=%s, 已传输=%.2f MB",
			requestID[:8]+"...", float64(written)/(1024*1024))

		// 🔥🔥🔥 关键优化：设置状态为浏览器断开，并返回特殊头部
		h.statusManager.SetStatus(requestID, common.RequestStatusBrowserDisconnected)

		// 🔥 立即关闭HTTP/2请求体,通知客户端停止传输
		if closer, ok := c.Request.Body.(io.Closer); ok {
			closer.Close()
		}

		pr.ErrorChan <- fmt.Errorf("浏览器已断开连接")

		// 🔥🔥🔥 返回特殊状态头，客户端收到后应立即停止发送
		// ⚠️  关键修复：不返回JSON响应体，避免Content-Length不匹配
		c.Header("X-Request-Status", "BROWSER_DISCONNECTED")
		c.Status(http.StatusGone)
		c.Abort() // 立即中止请求，不写入响应体
		return

	case err := <-errChan:
		if err != nil {
			log.Printf("❌ [HTTP/2响应] 传输失败: %v, RequestID=%s", err, requestID[:8]+"...")

			// 🔥 设置状态为错误
			h.statusManager.SetStatus(requestID, common.RequestStatusError)

			// 🔥 立即关闭HTTP/2请求体
			if closer, ok := c.Request.Body.(io.Closer); ok {
				closer.Close()
			}

			pr.ErrorChan <- err

			// 🔥 返回特殊状态头，不返回响应体
			c.Header("X-Request-Status", "ERROR")
			c.Status(http.StatusInternalServerError)
			c.Abort() // 立即中止，避免Content-Length不匹配
			return
		}
		// err == nil 表示传输成功完成
		h.statusManager.SetStatus(requestID, common.RequestStatusCompleted)

		// 🔥🔥🔥 关键修复：只有在传输成功完成后才发送通知
		log.Printf("✅ [HTTP/2响应] 响应转发完成: RequestID=%s, 大小=%.2f MB, 耗时=%v",
			requestID[:8]+"...", float64(written)/(1024*1024), time.Since(startTime))

		// 发送完成通知到 upload_notification.go
		log.Printf("📤 [HTTP/2响应] 准备发送完成通知到ResponseChan: RequestID=%s", requestID[:8]+"...")

		select {
		case pr.ResponseChan <- []byte("OK"):
			log.Printf("✅ [HTTP/2响应] 完成通知已发送: RequestID=%s", requestID[:8]+"...")
		case <-time.After(5 * time.Second):
			log.Printf("❌ [HTTP/2响应] 发送完成通知超时(接收方可能已退出): RequestID=%s", requestID[:8]+"...")
		}
	}

	c.JSON(http.StatusOK, gin.H{"message": "响应已转发", "bytes": written})
}

// WaitForResponse 等待响应（阻塞直到收到响应或超时）
func (h *HTTP2ResponseHandler) WaitForResponse(pr *PendingResponse) ([]byte, error) {
	defer h.UnregisterPendingResponse(pr.RequestID)

	// 创建超时定时器
	timer := time.NewTimer(pr.Timeout)
	defer timer.Stop()

	log.Printf("⏳ [HTTP/2响应] 等待响应: RequestID=%s, 超时=%v",
		pr.RequestID[:8]+"...", pr.Timeout)

	select {
	case responseData := <-pr.ResponseChan:
		duration := time.Since(pr.StartTime)
		log.Printf("✅ [HTTP/2响应] 收到响应: RequestID=%s, 大小=%.2f MB, 耗时=%v",
			pr.RequestID[:8]+"...", float64(len(responseData))/(1024*1024), duration)
		return responseData, nil

	case err := <-pr.ErrorChan:
		log.Printf("❌ [HTTP/2响应] 响应错误: RequestID=%s, 错误=%v",
			pr.RequestID[:8]+"...", err)
		return nil, err

	case <-timer.C:
		log.Printf("⏱️  [HTTP/2响应] 响应超时: RequestID=%s, 超时=%v",
			pr.RequestID[:8]+"...", pr.Timeout)
		return nil, fmt.Errorf("等待响应超时: %v", pr.Timeout)
	}
}

// GetPendingResponseCount 获取等待响应的请求数量
func (h *HTTP2ResponseHandler) GetPendingResponseCount() int {
	count := 0
	h.pendingResponses.Range(func(key, value interface{}) bool {
		count++
		return true
	})
	return count
}

// HandleRequestStatus 处理客户端请求状态查询
// 路由：GET /tunnel/request/status/:requestID
// 客户端可以在发送数据前调用此接口检查是否应该停止发送
func (h *HTTP2ResponseHandler) HandleRequestStatus(c *gin.Context) {
	requestID := c.Param("requestID")

	status, ok := h.statusManager.GetStatus(requestID)
	if !ok {
		// 请求不存在，应该停止发送
		c.JSON(http.StatusOK, gin.H{
			"status":      "NOT_FOUND",
			"should_stop": true,
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"status":      status.String(),
		"should_stop": status.ShouldStopSending(),
	})
}

// CleanupExpiredRequests 清理过期的请求（定期调用）
func (h *HTTP2ResponseHandler) CleanupExpiredRequests() {
	now := time.Now()
	expiredCount := 0

	h.pendingResponses.Range(func(key, value interface{}) bool {
		pr := value.(*PendingResponse)
		if now.Sub(pr.StartTime) > pr.Timeout {
			requestID := key.(string)

			// 🔥 设置状态为超时
			h.statusManager.SetStatus(requestID, common.RequestStatusTimeout)

			// 请求已超时，发送错误并删除
			select {
			case pr.ErrorChan <- fmt.Errorf("请求超时"):
			default:
			}
			h.pendingResponses.Delete(key)
			expiredCount++
		}
		return true
	})

	if expiredCount > 0 {
		log.Printf("🧹 [HTTP/2响应] 清理过期请求: %d个", expiredCount)
	}
}

// StartCleanupTimer 启动定期清理定时器
func (h *HTTP2ResponseHandler) StartCleanupTimer(interval time.Duration) {
	ticker := time.NewTicker(interval)
	go func() {
		for range ticker.C {
			h.CleanupExpiredRequests()
		}
	}()
}
